package demo.reflection;

import demo.annotation.MyAnnotation;
import demo.annotation.InheritedMarker;
import demo.override.ChildService;
import demo.override.ParentService;
import demo.suppress.SuppressWarningsDemo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


 //反射综合示例
//三种获取Class对象方式
//获取所有方法与属性（getDeclaredMethods/getDeclaredFields）
 //构造真实类对象（newInstance / 构造器）
//执行方法 invoke
 //设置属性 set + setAccessible(true)
  //读取类上的注解与注解属性
 // 演示 @Inherited/@Override/@SuppressWarnings

public class ReflectionExamples {
    public static void main(String[] args) throws Exception {
        // 1) 三种方式获取Class
        Class<?> c1 = Class.forName("demo.reflection.User"); // 1. Class.forName("包名.类名")
        Class<?> c2 = User.class;                           // 2. 类名.class
        Class<?> c3 = new User().getClass();                // 3. 对象.getClass()
        System.out.println("Class refs: " + c1 + ", " + c2 + ", " + c3);

        // 2) 获取所有方法和属性（声明的，包括private）
        System.out.println("Methods (declared):");
        for (Method m : c1.getDeclaredMethods()) {
            System.out.println("  " + m);
        }
        System.out.println("Fields (declared):");
        for (Field f : c1.getDeclaredFields()) {
            System.out.println("  " + f);
        }

        // 3) 构造真实类对象
        Object u1 = c1.newInstance(); // 旧写法（教学演示），在新版本中建议使用构造器
        Constructor<?> ctor = c1.getDeclaredConstructor();
        Object u2 = ctor.newInstance(); // 新写法

        // 4) 执行方法：设置年龄、读取姓名
        Method setAge = c1.getDeclaredMethod("setAge", int.class);
        setAge.invoke(u1, 25);
        Method getAge = c1.getDeclaredMethod("getAge");
        System.out.println("u1 age via invoke: " + getAge.invoke(u1));

        // 5) 设置属性：含private字段，需 setAccessible(true)
        Field nameField = c1.getDeclaredField("name");
        nameField.setAccessible(true); // 允许访问private
        nameField.set(u1, "Alice");
        Method getName = c1.getDeclaredMethod("getName");
        System.out.println("u1 name via private field set: " + getName.invoke(u1));

        Field idField = c1.getDeclaredField("id");
        idField.setInt(u1, 1);
        Field sexField = c1.getDeclaredField("sex");
        sexField.setInt(u1, 0);
        Field ctField = c1.getDeclaredField("createTime");
        ctField.set(u1, "2025-01-01");

        // 6) 读取类上的注解对象与属性值
        MyAnnotation ann = c1.getDeclaredAnnotation(MyAnnotation.class);
        if (ann != null) {
            System.out.println("@MyAnnotation -> value=" + ann.value() + ", author=" + ann.author() + ", version=" + ann.version());
        }

        // 7) 演示 @Inherited：父类标注注解，子类也能读取到
        InheritedMarker pAnn = ParentService.class.getAnnotation(InheritedMarker.class);
        InheritedMarker cAnn = ChildService.class.getAnnotation(InheritedMarker.class);
        System.out.println("ParentService has @InheritedMarker? " + (pAnn != null));
        System.out.println("ChildService has @InheritedMarker? " + (cAnn != null));

        // 8) 演示 @Override：子类重写父类方法
        ChildService child = new ChildService();
        System.out.println("Override demo -> " + child.run());

        // 9) 演示 @SuppressWarnings：抑制警告输出（编译期行为，运行时仅看到正常打印）
        new SuppressWarningsDemo().callLegacy();
    }
}

